/*global pi, RefResource */
// 异步模块，提供异步函数对象，和auto功能
/*
auto 是 大型编码中使用频率非常高的方法之一。它能方便组织功能中多个任务的顺序执行和异步并发执行，可以解决任务依赖关系。
拿板贴入库的功能来说，需要考虑以下几点：
	判断用户登录状态 
	判断用户提交数据的合法性 
	分析并获得可以存储的板贴数据 
	查询并确认板贴所属贴板是否有效（是否存在，以及是否为发布者拥有） 
	板贴入库 
	更新关联操作（比如用户的板贴数、板贴列表，贴板的板贴数和板贴列表等等） 
	产生用户动态 
	产生标签动态 
	通知关注者, 贴板成员，贴板作者 
	最后返回结果 

	这一系列任务，如果组织不好，代码会相当凌乱，难以维护，借助 async.auto，产生了清晰明了的代码： 
async.auto({
	// 分析并获取有效数据
	datas: function (callback) {},
	// 查贴板，确认是否存在
	board: function (callback) {},
	// 入库贴板内容
	post: ['datas', 'board', function (datas, board, callback) {}],
	// 更新贴板表和用户表
	updateBoardAndUser: ['post', function (post, callback) {}],
	// 产生用户动态
	feed: ['post', function(post, callback) {}],
	// 产生标签动态
	tagFeed: ['feed', function (feed, callback) {}],
	// 通知关注者, 贴板成员，贴板作者
	notify: ['post', function (post, callback) {}]
// 返回JSON结果
}, function (result) {});

*/

pi.mod.define('pi.async', function(pi) {
	"use strict";
	// 定义模块
	var module = {},
	// 创建一个异步函数
	create = function() {
		var then, result, next, fun = function(r) {
			if (r === undefined) {
				r = [];
			}
			if (then !== undefined) {
				then.apply(undefined, r.push(next));
			} else {
				result = r;
			}
		};
		fun.then = function(t) {
			next = create();
			if (result !== undefined) {
				t.apply(undefined, result.push(next));
			} else {
				then = t;
			}
			return next;
		};
		return fun;
	},
	//mapreduce算法，参数array为数组，使用mapFunc函数，发送请求，等待所有回应
	mapReduce = function(array, mapFunc, callback) {
		var i, fun, arr, amount = array.length;
		if (amount === 0) {
			callback([]);
			return;
		}
		fun = function(index) {
			return function(result) {
				arr[index] = result;
				if (result.error) {
					arr.error = result.error;
					arr.reason = result.reason;
				}
				amount--;
				if (amount < 1) {
					callback(arr);
				}
			};
		};
		arr = [];
		arr.length = amount;
		for (i = amount - 1; i >= 0; i--) {
			mapFunc(array[i], fun(i));
		}
	};
	module.create = create;
	module.mapReduce = mapReduce;
	//组织功能中多个任务的顺序执行和异步并发执行，可以解决任务依赖关系
	module.auto = function(cfg, callback) {
		var i, next, amount = 0,
		wait = {},
		ok = {},
		fun = function(key) {
			return function(result) {
				if (next) {
					if (result.error) {
						next = undefined;
						result.key = key;
						callback(result);
						return;
					}
					amount--;
					ok[key] = result;
					return (amount > 0) ? next() : callback(ok);
				}
			};
		};
		for (i in cfg) {
			if (cfg.hasOwnProperty(i)) {
				wait[i] = cfg[i];
				amount++;
			}
		}
		if(amount === 0){
			return callback(ok);
		}
		next = function() {
			var i, j, n, v, arr;
			for (i in wait) {
				if (wait.hasOwnProperty(i)) {
					v = wait[i];
					if (pi.lang.isFunction(v)) {
						delete wait[i];
						v(fun(i));
						continue;
					}
					for (j = 0, n = v.length - 1; j < n; j++) {
						if (!ok[v[j]]) {
							break;
						}
					}
					if (j >= n) {
						delete wait[i];
						arr = [];
						arr.length = n + 1;
						for (j = 0; j < n; j++) {
							arr[j] = ok[v[j]];
						}
						arr[n] = fun(i);
						v[n].apply(undefined, arr);
					}
				}
			}
		};
		next();
	};
	return module;
});